package parttwo.homework;

import java.util.Scanner;

/**
 * 1.对棋盘的数组进行初始化，使得每一个值为 0
 * 2.定义绘制棋盘的成员方法getQiPan
 * 3.提示黑方和白方分别下棋并重新绘制棋盘play
 * 4.判定输赢。
 */

public class FiveInALow {
//    定义一个私有成员变量表示黑棋是否赢
    private boolean isBlackWin;
//    定义一个私有成员变量表示白棋是否赢
    private boolean isWhiteWin;
//   定义一个二维length为16的数组，使用 0: 空白 1：黑棋 * 2：白棋 ^
    private int[][] qiPan ;

    public void setBlackWin(boolean blackWin) {
        isBlackWin = blackWin;
    }

    public void setWhiteWin(boolean whiteWin) {
        isWhiteWin = whiteWin;
    }

    public void setQiPan(int[][] qiPan) {
        this.qiPan = qiPan;
    }

    //    构造方法，实现成员变量的初始化。
    public FiveInALow() {
        setBlackWin(false);
        setWhiteWin(false);
        setQiPan(new  int[16][16]);
    }

//    第一步 初始化棋盘对应的数组，使其全为0,0 代表棋盘没有值
    public void initQiPan(){
        for (int i = 0; i < 16; i++) {
            for (int j = 0; j < 16; j++) {
                qiPan[i][j] = 0;
            }
        }
    }
//    第二步 打印棋盘
    public  void getQiPan(){
        for (int i= 0;i<qiPan.length;i++){
            for (int j = 0; j <qiPan[i].length; j++) {
//                2.1 棋盘边缘
                if (i ==0 && j== 0){
                    System.out.print("  ");
                } else if (i == 0){
                    System.out.printf("%x",j);
                    System.out.print("   ");
                } else if (j == 0){
                    System.out.printf("%x",i);
                    System.out.print(" ");
                }
//                2.2 棋盘内容  1 代表: * 代表: 黑棋 ;
//                             2 代表: ^ 代表: 白棋 ;
//                             0 代表: + 代表: 没有棋子
                else if (qiPan[i][j] == 1){
                    System.out.print("*"+"   ");
                }else if (qiPan[i][j] == 2){
                    System.out.print("^"+"   ");
                }else if (qiPan[i][j] == 0){
                    System.out.print("+"+"   ");
                }
            }
            System.out.println();
        }
    }
//    第三步，进行下棋
    public void play(){
        Scanner scanner = new Scanner(System.in);
//      3.1 使得游戏能够一直循环进行下棋的过程，直到某一方赢
        while (true){
            int black_x;    // 黑棋横坐标
            int black_y;    // 黑棋纵坐标
            int white_x;    // 白棋横坐标
            int white_y;    // 白棋纵坐标

//           3.2 当白方没有赢时，轮到黑方下棋，同时需要判断其位置是否合法，以及其位置上是否已经有棋子。
            if (isWhiteWin == false){
//                3.2.1 行输入值范围判断，可能存在多次输入值非法，故需要使用while循环，直到输入值合法。
                System.out.println("请 黑 方下黑棋，说出黑棋子所在 行 (0-15) ,*代表黑棋,^代表白棋：");
                while (true) {
                    black_x = scanner.nextInt();
                    if (black_x < 0 || black_x > 15) {
                        System.out.println("输入值非法，请输入（0-15）的值:");
                        System.out.println("请黑方下黑棋，说出黑棋子所在行(0-15)：");
                        black_x = scanner.nextInt();
                    } else {
                        break;
                    }
                }

//                3.2.2 行输入值范围判断，可能存在多次输入值非法，故需要使用while循环，直到输入值合法。
                System.out.println("请 黑 方下黑棋，说出黑棋子所在 列( 0-15) ,*代表黑棋,^代表白棋：");
                while (true){
                    black_y = scanner.nextInt();
                    if (black_y<0 || black_y >15) {
                        System.out.println("输入值非法，请输入（0-15）的值");
                        black_y = scanner.nextInt();
                    }else {
                        break;
                    }
                }
//                3.2.3 可能存在多次输入值位置非空，故需要无线循环，直到输入的位置的值为空  即数组qiPan对应的值为  0
                while (true){
    //                3.2.4 如果qiPan数组的值不为0  表示此处已经有棋，需要从新输入。
                    if (qiPan[black_x][black_y] != 0 ){
                        System.out.println("此处已经有棋，请重新选择！");
                        System.out.println("请 黑 方下黑棋，说出黑棋子所在 行(0-15) ,*代表黑棋,^代表白棋：");
    //                    3.2.3.1 同样需要输入值的合法性判断
                        while (true) {
                            black_x = scanner.nextInt();
                            if (black_x < 0 || black_x > 15) {
                                System.out.println("输入值非法，请输入（0-15）的值:");
                                black_x = scanner.nextInt();
                            } else {
                                break;
                            }
                        }
    //                    3.2.3.2 同样需要输入值的合法性判断
                        System.out.println("请 黑 方下黑棋，说出黑棋子所在 列(0-15) ,*代表黑棋,^代表白棋：");
                        while (true) {
                            black_x = scanner.nextInt();
                            if (black_x < 0 || black_x > 15) {
                                System.out.println("输入值非法，请输入（0-15）的值:");
                                black_x = scanner.nextInt();
                            } else {
                                break;
                            }
                        }
                    }
    //                3.2.5 如果值合法，且输入位置未有棋子，便可进行下棋，即将数组相应的位置变为 1  表示此处为黑棋，判断输赢，打印棋盘
                    else {
                        qiPan[black_x][black_y] = 1;
                        this.isWin();
                        this.getQiPan();
                        break;
                    }
                }
//           3.3 如果白棋赢，则停止下棋，跳出无线循环。
            }else {
                System.out.println("白棋胜出！");
                break;
            }

//            此处逻辑与下黑棋的过程一样。
//           3.3 当黑方没有赢时，轮到白方下棋，同时需要判断其位置是否合法，以及其位置上是否已经有棋子。
            if (isBlackWin==false){
                System.out.println("请 白 方下白棋，说出白棋子所在 行(0-15) ,*代表黑棋,^代表白棋：");
                while (true) {
                    white_x = scanner.nextInt();
                    if (white_x < 0 || white_x > 15) {
                        System.out.println("输入值非法，请输入（0-15）的值:");
                        System.out.println("请 白 方下黑棋，说出白棋子所在行(0-15) ,*代表黑棋,^代表白棋：：");
                        white_x = scanner.nextInt();
                    } else {
                        break;
                    }
                }

                System.out.println("请 白 方下白棋，说出白棋子所在 列(0-15) ,*代表黑棋,^代表白棋：");
                while (true) {
                    white_y = scanner.nextInt();
                    if (white_y < 0 || white_y > 15) {
                        System.out.println("输入值非法，请输入（0-15）的值:");
                        System.out.println("请 白 方下黑棋，说出白棋子所在行(0-15) ,*代表黑棋,^代表白棋：：");
                        white_y = scanner.nextInt();
                    } else {
                        break;
                    }
                }

                while (true){
                    if (qiPan[white_x][white_y] != 0){
                        System.out.println("此处有棋子，请重新选择！");
                        System.out.println("请 白 方下白棋，说出白棋子所在 行(0-15) ,*代表黑棋,^代表白棋：");
                        while (true) {
                            white_x = scanner.nextInt();
                            if (white_x < 0 || white_x > 15) {
                                System.out.println("输入值非法，请输入（0-15）的值:");
                                System.out.println("请 白 方下黑棋，说出白棋子所在行(0-15) ,*代表黑棋,^代表白棋：：");
                                white_x = scanner.nextInt();
                            } else {
                                break;
                            }
                        }
                        System.out.println("请 白 方下白棋，说出白棋子所在 列(0-15) ,*代表黑棋,^代表白棋：");
                        while (true) {
                            white_y = scanner.nextInt();
                            if (white_y < 0 || white_y > 15) {
                                System.out.println("输入值非法，请输入（0-15）的值:");
                                System.out.println("请 白 方下黑棋，说出白棋子所在行(0-15) ,*代表黑棋,^代表白棋：：");
                                white_y = scanner.nextInt();
                            } else {
                                break;
                            }
                        }
                    }
                    else {
                        qiPan[white_x][white_y] = 2;
                        this.isWin();
                        this.getQiPan();
                        break;
                    }

                }

            }
            else {
                System.out.println("黑棋胜出！");
                break;
            }
        }


    }
//    第四步 判断是哪一方赢。
    public void isWin(){
//        以当前棋子坐标为中点，向八个方向延伸两颗，当同一线上有五颗，即判定为赢家，
//        注意范围：即当横向判定时，其中心棋子位置应该属于大于等于第二列，小于等于第十四列
//                 即当竖向判定时，其中心棋子位置应该属于大于等于第二行，小于等于第十四行
//                 即当斜向判定时，其中心棋子位置应该属于大于等于第二行，小于等于第十四行，
//                 同时 其中心棋子位置应该属于大于等于第二行，小于等于第十四行
        for (int i = 0; i < qiPan.length; i++) {
            for (int j = 0; j < qiPan[i].length; j++) {
//              4.1   黑棋赢
//              4.1.1 横着有五颗  向左两位 向左一位 向右一位 向右两位  同时有  赢
                if (j <=13 && j >=2){
                    if (qiPan[i][j] == 1 && qiPan[i][j+1] == 1 && qiPan[i][j+2] == 1
                        && qiPan[i][j-1] == 1 && qiPan[i][j-2] == 1){
                        isBlackWin = true;
                    }
                }
//                4.1.2 竖着有五颗
                if (i <=13 && i >=2){
                    if (qiPan[i][j] == 1 && qiPan[i+1][j] == 1 && qiPan[i+2][j] == 1
                        && qiPan[i-1][j] == 1 && qiPan[i-2][j] == 1){
                        isBlackWin = true;
                    }
                }
//                4.1.3 斜角 右上角到左下角
                if (i <=13 && i >=2 && j<=13 && j>=2){
                    if (qiPan[i][j] == 1 && qiPan[i-1][j+1] == 1 && qiPan[i-2][j+2] == 1
                        && qiPan[i+1][j-1] == 1 && qiPan[i+2][j-2] == 1){
                        isBlackWin = true;
                    }
                }
//                4.1.3 斜巷 左上角到右下角
                if (i <=13 && i >=2 && j<=13 && j>=2){
                    if (qiPan[i][j] == 1 && qiPan[i+1][j+1] == 1 && qiPan[i+2][j+2] == 1
                        && qiPan[i-1][j-1] == 1 && qiPan[i-2][j-2] == 1){
                        isBlackWin = true;
                    }
                }

//                4.2   白棋赢
//              4.2.1 横着有五颗
                if (j <=13 && j >=2){
                    if (qiPan[i][j] == 2 && qiPan[i][j+1] == 2 && qiPan[i][j+2] == 2
                        && qiPan[i][j-1] == 2 && qiPan[i][j-2] == 2){
                        isWhiteWin = true;
                    }
                }
//                4.2.2 竖着有五颗
                if (i <=13 && i >=2){
                    if (qiPan[i][j] == 2 && qiPan[i+1][j] == 2 && qiPan[i+2][j] == 2
                        && qiPan[i-1][j] == 2 && qiPan[i-2][j] == 2){
                        isWhiteWin = true;
                    }
                }
//                4.2.3 斜巷 右上角到左下角
                if (i <=13 && i >=2 && j<=13 && j>=2){
                    if (qiPan[i][j] == 2 && qiPan[i-1][j+1] == 2 && qiPan[i-2][j+2] == 2
                        && qiPan[i+1][j-1] == 2 && qiPan[i+2][j-2] == 2){
                        isWhiteWin = true;
                    }
                }
//                4.2.3 斜巷 左上角到右下角
                if (i <=13 && i >=2 && j<=13 && j>=2){
                    if (qiPan[i][j] == 2 && qiPan[i+1][j+1] == 2 && qiPan[i+2][j+2] == 2
                        && qiPan[i-1][j-1] == 2 && qiPan[i-2][j-2] == 2){
                        isWhiteWin = true;
                    }
                }

            }
        }
    }


}
